﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Gqq.Csharpindepth.Chapter23
{

    //interface IComparer<T>
    //{
    //    int Comparer(T value);
    //}
    /// <summary>
    /// IComparable和IComparaer
    /// IComparaer：只需要实现Compare方法即可。
    /// 但是，一般不推荐实现IComparaer接口，而是去继承Compare<T>泛型类。
    /// 如果一个类实现了IComparable，那么表示这个类是“可以比较的”，或者说是有顺序的。
    /// 总的来说，一个类实现IComparable接口是很必须的。
    /// 1、它可以利用List<T>.Sort()进行默认排序
    /// 2、它可以放在SortedList或者SortedSet<T>中
    /// 3、它可以作为泛型类的参数。class<T> where T:IComparable
    /// 4、可以作为泛型方法的实参。method<T> where T:IComparable
    /// 下例中的Box就实现了IComparable。
    /// 那么List<Box>.Sort或者SortedList<Box,TValue>都是可以用的。
    /// </summary>
    public class CompBox2ByLength : Comparer<Box2>
    {
        public override int Compare(Box2 x, Box2 y)
        {
            //throw new NotImplementedException();
            // Compares by Length, Height, and Width.

            if (x.Length.CompareTo(y.Length) != 0)
            {
                return x.Length.CompareTo(y.Length);
            }
            else if (x.Height.CompareTo(y.Height) != 0)
            {
                return x.Height.CompareTo(y.Height);
            }
            else if (x.Width.CompareTo(y.Width) != 0)
            {
                return x.Width.CompareTo(y.Width);
            }
            else
            {
                return 0;
            }


        }
    }

    public class Box : IComparable<Box>
    {

        public Box(int h, int l, int w)
        {
            this.Height = h;
            this.Length = l;
            this.Width = w;
        }

        public int Height { get; private set; }
        public int Length { get; private set; }
        public int Width { get; private set; }

        public int CompareTo(Box other)
        {
            // Compares Height, Length, and Width.
            if (this.Width.CompareTo(other.Width) != 0)
            {
                return this.Width.CompareTo(other.Width);
            }
            else if (this.Length.CompareTo(other.Length) != 0)
            {
                return this.Length.CompareTo(other.Length);
            }
            else if (this.Height.CompareTo(other.Height) != 0)
            {
                return this.Height.CompareTo(other.Height);
            }
            else
            {
                return 0;
            }
        }

        public static int Compare<T>(T t1, T t2) where T : IComparable<T>
        {
            return t1.CompareTo(t2);
        }

        public static void TestResult()
        {
            List<Box2> box2s = new List<Box2>();
            box2s.Add(new Box2(4, 20, 14));
            box2s.Add(new Box2(12, 12, 12));
            box2s.Add(new Box2(8, 20, 10));
            box2s.Add(new Box2(6, 10, 2));

            //由于Box没有实现IComparable，所以如果使用Boxes.Sort()，运行的时候就会出错。
            //因为系统不知道如何比较。
            box2s.Sort(new CompBox2ByLength());

            Console.WriteLine("H - L - W");
            Console.WriteLine("==========");
            foreach (Box2 bx in box2s)
            {
                Console.WriteLine("{0}\t{1}\t{2}",
                    bx.Height, bx.Length,
                    bx.Width);
            }

            List<Box> boxes = new List<Box>();
            boxes.Add(new Box(4, 20, 14));
            boxes.Add(new Box(12, 12, 12));
            boxes.Add(new Box(8, 20, 10));
            boxes.Add(new Box(6, 10, 2));

            //由于Box没有实现IComparable，所以如果使用Boxes.Sort()，运行的时候就会出错。
            //因为系统不知道如何比较。
//            boxes.Sort((b1, b2) => b1.Height.CompareTo(b2.Height));

            boxes.Sort();
            Console.WriteLine("H - L - W");
            Console.WriteLine("==========");
            foreach (Box bx in boxes)
            {
                Console.WriteLine("{0}\t{1}\t{2}",
                    bx.Height, bx.Length,
                    bx.Width);
            }

            GeneralBox<Box> b = new GeneralBox<Box>(new Box(8, 3, 1), new Box(4, 5, 6), new Box(2, 1, 3));
            Console.WriteLine("H - L - W");
            Console.WriteLine("==========");
            foreach (var bx in b.Lists)
            {
                Console.WriteLine("{0}\t{1}\t{2}",
                    bx.Height, bx.Length,
                    bx.Width);
            }
            int r = Compare(new Box(3, 5, 7), new Box(7, 5, 3));
            Console.WriteLine(r);

            //由于Box2没有实现IComparable<Box2>接口，所以不能构造这个泛型类。
//            GeneralBox<Box2> b2 = new GeneralBox<Box2>();

        }
    }

    /// <summary>
    /// 没有实现IComparable的类
    /// </summary>
    public class Box2
    {

        public Box2(int h, int l, int w)
        {
            this.Height = h;
            this.Length = l;
            this.Width = w;
        }

        public int Height { get; private set; }
        public int Length { get; private set; }
        public int Width { get; private set; }

       
    }

    /// <summary>
    /// 一个有约束的泛型类。T必须实现IComparable接口
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class GeneralBox<T> where T : IComparable<T>
    {
        //因为用到了SortedSet，因此必须要T实现IComparable接口
        public SortedSet<T> Lists { set; get; }

        public GeneralBox(T t1, T t2, T t3)
        {
            if (Lists == null)
                Lists = new SortedSet<T>();
            Lists.Add(t1);
            Lists.Add(t2);
            Lists.Add(t3);
        }
    }

}
